import Request from '../request/request';
import { encryptAES, decryptAES } from '../utils/aes';
import AlgorithmService from './algorithm_service';
import CryptoJS, { lib } from 'crypto-js';
import Env from '../utils/env'

const version = 1;

/**
 * HttpService
 * 
 * 基础 HTTP 请求服务类，用于封装项目中常用的 GET POST 请求逻辑。
 * 所有业务服务类（如 MqttService）都可继承该类进行统一接口调用。
 */
export default class HttpService extends AlgorithmService {
  constructor() {

    super();
  }

  private generateUUID128Bit(): string {
    // 生成 16 字节（128 bit）随机数
    const random = CryptoJS.lib.WordArray.random(16);

    // 转为十六进制字符串
    const hex = random.toString(CryptoJS.enc.Hex);

    // 格式化成 UUID 样式：8-4-4-4-12
    return (
      hex.substring(0, 8) + '-' +
      hex.substring(8, 12) + '-' +
      hex.substring(12, 16) + '-' +
      hex.substring(16, 20) + '-' +
      hex.substring(20, 32)
    );
  }

  private getHeadersAndParams() {
    const requestId = this.generateUUID128Bit();
    const timestamp = +new Date();
    const headers: {[key: string]: any} = {
      clientId: Env.clientId,
      clientSecret: Env.clientSecret,
      version,
      requestId,
      timestamp
    }
    const joinString = this.objectToQueryString(headers);
    const sign = CryptoJS.SHA256(joinString).toString();
    // Logger.log("clientId", Env.clientId);
    // Logger.log("clientSecret", Env.clientSecret);
    // Logger.log("joinString", joinString);
    // Logger.log("sign", sign);
    // Logger.log("requestId", requestId);
    headers.sign = sign;
    delete headers.clientSecret;
    const data = {
      clientId: Env.clientId,
      requestId,
    };
    return {
      headers,
      data
    };
  }

  private objectToQueryString(obj: {[key: string]: any}) {
    return Object.entries(obj)
      .map(([key, value]) => `${key}=${value}`)
      .join('&');
  }

  async get(path: string, params: any) {
    const { headers, data } = this.getHeadersAndParams();
    
    return await Request.send({
      path,
      method: 'GET',
      params: {
        // ...data,
        // payload: {
        //   ...params,
        // }
        ...params,
      },
      headers: {
        authorization: "Bearer abe0e90a-5fe5-4e22-bfa0-a01e34f52483",
        locale: "zh_CN",
        ...headers
      },
    });
  }

  async post(path: string, params: any = {}) {
    const { headers, data } = this.getHeadersAndParams();
    return await Request.send({
      path,
      method: 'POST',
      params: {
        // ...data,
        payload: params,
        header: {
          ...headers
        }
      },
      // headers: {
      //   ...headers
      // },
    });
  }

  // 接口请求测试
  async apiTest() {
    return await this.get('/auth/oauth/QRCode/token', {
      uuid: '5f4ac10f56274f608a097977e57a008c',
      codeType: 'login'
    })
  }

  // 获取Mqtt配置
  async getMqttConnConfig() {
    return await this.get("/elf/V2.0/device/mqttConnConfig", {
      clientName: 'lite-mini',
      protocolType: 'wx'
    });
  }

  // MQTT-获取联网信息
  async getMqttConnectConfig() {
    return await this.post("/elf/open-invoke-api/device-config/m/3c", {
      cnct: encryptAES(Env.cnct),
      protocolType: Env.protocolType
    });
  }

  // MQTT-获取订阅主题
  async getMqttSubTopics(deviceCode: string) {
    return await this.post("/elf/open-invoke-api/device-config/m/sts", {
      cnct: encryptAES(Env.cnct),
      deviceCode
    });
  }

  // 日报告-通过报告ID获取报告详情
  async getDaySleepById(params: OpenDaySleepByIdDto) {
    return await this.post("/elf/open-invoke-api/sleep/d/info", {
      version: "V5.0.0",
      ...params,
      clientId: Env.clientId
    });
  }

  // 日报告-获取指定日期设备最新报告
  async getDaySleep(params: OpenDaySleepVo) {
    return await this.post("/elf/open-invoke-api/sleep/d/latest", {
      version: "V5.0.0",
      ...params,
      clientId: Env.clientId
    });
  }

  // 日报告-获取设备日历统计数据
  async getDaySleepCalendar(params: OpenDaySleepVo) {
    return await this.post("/elf/open-invoke-api/sleep/d/list", {
      version: "V5.0.0",
      ...params,
      clientId: Env.clientId
    });
  }

  // 周月报告-通过报告ID获取报告详情
  async getWeekMonthSleepById(params: OpenWeekMonthSleepByIdDto) {
    return await this.post("/elf/open-invoke-api/sleep/wm/info", {
      reqVersion: "V2",
      ...params,
      clientId: Env.clientId
    });
  }

  // 周月报告-获取指定日期设备最新报告
  async getWeekMonthSleep(params: OpenWeekMonthSleepDto) {
    return await this.post("/elf/open-invoke-api/sleep/wm/latest", {
      reqVersion: "V2",
      ...params,
      clientId: Env.clientId
    });
  }

  // 周月报告-获取设备日历统计数据
  async getWeekMonthSleepCalendar(params: OpenWeekMonthSleepDto) {
    return await this.post("/elf/open-invoke-api/sleep/wm/list", {
      reqVersion: "V2",
      ...params,
      clientId: Env.clientId
    });
  }

  // 日报告-生成报告
  async dayReportPreForceGenerate(params: OpenDayPreForceGenerateDto) {
    return await this.post("/elf/open-invoke-api/sleep/d/pre-force-generate", {
      ...params,
      clientId: Env.clientId
    });
  }
}




type OpenDaySleepByIdDto = {
  docId?: string
  version?: string
  machineUniqueCode?: string
  clientId?: string
}

type OpenDaySleepVo = {
  docDate?: string // "yyyy/MM/dd"
  version?: string
  clientId?: string
  machineUniqueCode?: string
}

type OpenWeekMonthDocPageDto = {
  docDate?: string // "yyyy/MM/dd"
  periodType?: string
  clientId?: string
  machineUniqueCode?: string
}

type OpenWeekMonthSleepByIdDto = {
  docId?: string
  reqVersion?: string
  clientId?: string
  machineUniqueCode?: string
}

type OpenWeekMonthSleepDto = {
  periodType?: string
  reqVersion?: string
  docDate?: string // "yyyy/MM/dd"
  clientId?: string
  machineUniqueCode?: string
}

type OpenMqttConnectConfigDto = {
  cnct?: string
  protocolType?: string
}

type OpenMqttResultVo = {
  enStr?: string
  enType?: number
}

type OpenMqttSubTopicsDto = {
  cnct?: string
  deviceCode?: string
}

type OpenDayPreForceGenerateDto = {
    machineCode: string
    machineEntityPartCode: string
}
